#pragma once

#include <spdlog/fmt/fmt.h>
#include <spdlog/sinks/rotating_file_sink.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>

#include <iostream>
#include <memory>
#include <string>
#include <thread>

// 为 std::thread::id 创建格式化器特化
template <>
struct fmt::formatter<std::thread::id> {
    constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) {
        return ctx.begin();
    }

    template <typename FormatContext>
    auto format(const std::thread::id& id, FormatContext& ctx) const
        -> decltype(ctx.out()) {
        std::stringstream ss;
        ss << id;
        return fmt::format_to(ctx.out(), "{}", ss.str());
    }
};

namespace common {

/**
 * @brief 日志工具类，用于初始化和管理日志
 */
class Logger {
   public:
    /**
     * @brief 初始化日志系统
     * @param log_level 日志级别
     * @param log_filename 日志文件名
     * @param max_size 单个日志文件最大大小（字节）
     * @param max_files 最大日志文件数量
     */
    static void init(spdlog::level::level_enum log_level = spdlog::level::info,
                     const std::string& log_filename = "logs/app.log",
                     size_t max_size = 1048576 * 5,  // 5MB
                     size_t max_files = 3);

    /**
     * @brief 获取主日志器实例
     * @return 日志器实例
     */
    static std::shared_ptr<spdlog::logger>& getLogger();

   private:
    static std::shared_ptr<spdlog::logger> s_logger;
    static bool s_initialized;
};

}  // namespace common

// 日志宏定义，简化使用
#define LOG_TRACE(...) \
    SPDLOG_LOGGER_TRACE(common::Logger::getLogger(), __VA_ARGS__)
#define LOG_DEBUG(...) \
    SPDLOG_LOGGER_DEBUG(common::Logger::getLogger(), __VA_ARGS__)
#define LOG_INFO(...) \
    SPDLOG_LOGGER_INFO(common::Logger::getLogger(), __VA_ARGS__)
#define LOG_WARN(...) \
    SPDLOG_LOGGER_WARN(common::Logger::getLogger(), __VA_ARGS__)
#define LOG_ERROR(...) \
    SPDLOG_LOGGER_ERROR(common::Logger::getLogger(), __VA_ARGS__)
#define LOG_CRITICAL(...) \
    SPDLOG_LOGGER_CRITICAL(common::Logger::getLogger(), __VA_ARGS__)